import { ref, watch, unref } from 'vue';
import { useThrottleFn, useDebounceFn } from '@vueuse/core';

// 导出一个名为useEventListener的函数，该函数接收一个对象作为参数
export function useEventListener({ el = window, name, listener, options, autoRemove = true, isDebounce = true, wait = 80 }) {
	// 初始化一个空函数remove
	let remove = () => {};
	// 创建一个响应式引用isAddRef，并设置初始值为false
	const isAddRef = ref(false);

	// 如果el存在
	if (el) {
		// 创建一个响应式引用element，并设置初始值为el
		const element = ref(el);

		// 根据isDebounce的值，使用useDebounceFn或useThrottleFn创建一个函数handler
		const handler = isDebounce ? useDebounceFn(listener, wait) : useThrottleFn(listener, wait);
		// 如果wait存在，则realHandler为handler，否则为listener
		const realHandler = wait ? handler : listener;
		// 创建一个函数removeEventListener，用于移除事件监听
		const removeEventListener = (e) => {
			isAddRef.value = true;
			e.removeEventListener(name, realHandler, options);
		};
		// 创建一个函数addEventListener，用于添加事件监听
		const addEventListener = (e) => e.addEventListener(name, realHandler, options);

		// 创建一个watcher，监听element的变化
		const removeWatch = watch(
			element,
			(v, _ov, cleanUp) => {
				if (v) {
					// 如果v存在且isAddRef的值为false，则添加事件监听
					!unref(isAddRef) && addEventListener(v);
					// 清理函数，在watcher停止监听时执行
					cleanUp(() => {
						// 如果autoRemove为true，则移除事件监听
						autoRemove && removeEventListener(v);
					});
				}
			},
			{ immediate: true }
		);

		// 更新remove函数，使其可以移除事件监听并停止watcher
		remove = () => {
			removeEventListener(element.value);
			removeWatch();
		};
	}
	// 返回一个对象，该对象包含一个名为removeEvent的方法，该方法用于移除事件监听
	return { removeEvent: remove };
}
